

<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
  <meta charset="utf-8">
  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  <title>dscribe.descriptors.mbtr &mdash; DScribe 0.3.0a0 documentation</title>
  

  
  
  
  

  
  <script type="text/javascript" src="../../../_static/js/modernizr.min.js"></script>
  
    
      <script type="text/javascript" id="documentation_options" data-url_root="../../../" src="../../../_static/documentation_options.js"></script>
        <script type="text/javascript" src="../../../_static/jquery.js"></script>
        <script type="text/javascript" src="../../../_static/underscore.js"></script>
        <script type="text/javascript" src="../../../_static/doctools.js"></script>
        <script type="text/javascript" src="../../../_static/language_data.js"></script>
        <script async="async" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-AMS-MML_HTMLorMML"></script>
    
    <script type="text/javascript" src="../../../_static/js/theme.js"></script>

    

  
  <link rel="stylesheet" href="../../../_static/css/theme.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../../../_static/css/style.css" type="text/css" />
    <link rel="author" title="About these documents" href="../../../about.html" />
    <link rel="index" title="Index" href="../../../genindex.html" />
    <link rel="search" title="Search" href="../../../search.html" /> 
</head>

<body class="wy-body-for-nav">

   
  <div class="wy-grid-for-nav">
    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search" >
          

          
            <a href="../../../index.html">
          

          
            
            <img src="../../../_static/logo.png" class="logo" alt="Logo"/>
          
          </a>

          
            
            
              <div class="version">
                0.3.0a0
              </div>
            
          

          
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../../../search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>

          
        </div>

        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          
            
            
              
            
            
              <ul>
<li class="toctree-l1"><a class="reference internal" href="../../../install.html">Installation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../tutorials/tutorials.html">Tutorials</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../doc/modules.html">Documentation</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../contributing.html">Contributing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../citing.html">Citing DScribe</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../../about.html">About</a></li>
</ul>

            
          
        </div>
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" aria-label="top navigation">
        
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../../../index.html">DScribe</a>
        
      </nav>


      <div class="wy-nav-content">
        
        <div class="rst-content">
        
          















<div role="navigation" aria-label="breadcrumbs navigation">

  <ul class="wy-breadcrumbs">
    
      <li><a href="../../../index.html">Docs</a> &raquo;</li>
        
          <li><a href="../../index.html">Module code</a> &raquo;</li>
        
      <li>dscribe.descriptors.mbtr</li>
    
    
      <li class="wy-breadcrumbs-aside">
        
      </li>
    
  </ul>

  
  <hr/>
</div>
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
            
  <h1>Source code for dscribe.descriptors.mbtr</h1><div class="highlight"><pre>
<span></span><span class="c1"># -*- coding: utf-8 -*-</span>
<span class="sd">&quot;&quot;&quot;Copyright 2019 DScribe developers</span>

<span class="sd">Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);</span>
<span class="sd">you may not use this file except in compliance with the License.</span>
<span class="sd">You may obtain a copy of the License at</span>

<span class="sd">    http://www.apache.org/licenses/LICENSE-2.0</span>

<span class="sd">Unless required by applicable law or agreed to in writing, software</span>
<span class="sd">distributed under the License is distributed on an &quot;AS IS&quot; BASIS,</span>
<span class="sd">WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span>
<span class="sd">See the License for the specific language governing permissions and</span>
<span class="sd">limitations under the License.</span>
<span class="sd">&quot;&quot;&quot;</span>
<span class="kn">import</span> <span class="nn">sys</span>
<span class="kn">import</span> <span class="nn">math</span>
<span class="kn">import</span> <span class="nn">numpy</span> <span class="k">as</span> <span class="nn">np</span>

<span class="kn">from</span> <span class="nn">scipy.sparse</span> <span class="k">import</span> <span class="n">lil_matrix</span><span class="p">,</span> <span class="n">coo_matrix</span>

<span class="kn">from</span> <span class="nn">ase</span> <span class="k">import</span> <span class="n">Atoms</span>
<span class="kn">import</span> <span class="nn">ase.data</span>

<span class="kn">from</span> <span class="nn">dscribe.core</span> <span class="k">import</span> <span class="n">System</span>
<span class="kn">from</span> <span class="nn">dscribe.descriptors</span> <span class="k">import</span> <span class="n">Descriptor</span>
<span class="kn">from</span> <span class="nn">dscribe.libmbtr.mbtrwrapper</span> <span class="k">import</span> <span class="n">MBTRWrapper</span>
<span class="kn">import</span> <span class="nn">dscribe.utils.geometry</span>


<div class="viewcode-block" id="MBTR"><a class="viewcode-back" href="../../../doc/dscribe.descriptors.html#dscribe.descriptors.mbtr.MBTR">[docs]</a><span class="k">class</span> <span class="nc">MBTR</span><span class="p">(</span><span class="n">Descriptor</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot;Implementation of the Many-body tensor representation up to :math:`k=3`.</span>

<span class="sd">    You can choose which terms to include by providing a dictionary in the</span>
<span class="sd">    k1, k2 or k3 arguments. This dictionary should contain information</span>
<span class="sd">    under three keys: &quot;geometry&quot;, &quot;grid&quot; and &quot;weighting&quot;. See the examples</span>
<span class="sd">    below for how to format these dictionaries.</span>

<span class="sd">    You can use this descriptor for finite and periodic systems. When dealing</span>
<span class="sd">    with periodic systems or when using machine learning models that use the</span>
<span class="sd">    Euclidean norm to measure distance between vectors, it is advisable to use</span>
<span class="sd">    some form of normalization.</span>

<span class="sd">    For the geometry functions the following choices are available:</span>

<span class="sd">    * :math:`k=1`:</span>

<span class="sd">       * &quot;atomic_number&quot;: The atomic numbers.</span>

<span class="sd">    * :math:`k=2`:</span>

<span class="sd">       * &quot;distance&quot;: Pairwise distance in angstroms.</span>
<span class="sd">       * &quot;inverse_distance&quot;: Pairwise inverse distance in 1/angstrom.</span>

<span class="sd">    * :math:`k=3`:</span>

<span class="sd">       * &quot;angle&quot;: Angle in degrees.</span>
<span class="sd">       * &quot;cosine&quot;: Cosine of the angle.</span>

<span class="sd">    For the weighting the following functions are available:</span>

<span class="sd">    * :math:`k=1`:</span>

<span class="sd">       * &quot;unity&quot;: No weighting.</span>

<span class="sd">    * :math:`k=2`:</span>

<span class="sd">       * &quot;unity&quot;: No weighting.</span>
<span class="sd">       * &quot;exp&quot; or &quot;exponential&quot;: Weighting of the form :math:`e^{-sx}`</span>

<span class="sd">    * :math:`k=3`:</span>

<span class="sd">       * &quot;unity&quot;: No weighting.</span>
<span class="sd">       * &quot;exp&quot; or &quot;exponential&quot;: Weighting of the form :math:`e^{-sx}`</span>

<span class="sd">    The exponential weighting is motivated by the exponential decay of screened</span>
<span class="sd">    Coulombic interactions in solids. In the exponential weighting the</span>
<span class="sd">    parameters **cutoff** determines the value of the weighting function after</span>
<span class="sd">    which the rest of the terms will be ignored and the parameter **scale**</span>
<span class="sd">    corresponds to :math:`s`. The meaning of :math:`x` changes for different</span>
<span class="sd">    terms as follows:</span>

<span class="sd">    * :math:`k=2`: :math:`x` = Distance between A-&gt;B</span>
<span class="sd">    * :math:`k=3`: :math:`x` = Distance from A-&gt;B-&gt;C-&gt;A.</span>

<span class="sd">    In the grid setup *min* is the minimum value of the axis, *max* is the</span>
<span class="sd">    maximum value of the axis, *sigma* is the standard deviation of the</span>
<span class="sd">    gaussian broadening and *n* is the number of points sampled on the</span>
<span class="sd">    grid.</span>

<span class="sd">    If flatten=False, a list of dense np.ndarrays for each k in ascending order</span>
<span class="sd">    is returned. These arrays are of dimension (n_elements x n_elements x</span>
<span class="sd">    n_grid_points), where the elements are sorted in ascending order by their</span>
<span class="sd">    atomic number.</span>

<span class="sd">    If flatten=True, a scipy.sparse.coo_matrix is returned. This sparse matrix</span>
<span class="sd">    is of size (1, n_features), where n_features is given by</span>
<span class="sd">    get_number_of_features(). This vector is ordered so that the different</span>
<span class="sd">    k-terms are ordered in ascending order, and within each k-term the</span>
<span class="sd">    distributions at each entry (i, j, h) of the tensor are ordered in an</span>
<span class="sd">    ascending order by (i * n_elements) + (j * n_elements) + (h * n_elements).</span>

<span class="sd">    This implementation does not support the use of a non-identity correlation</span>
<span class="sd">    matrix.</span>
<span class="sd">    &quot;&quot;&quot;</span>
<div class="viewcode-block" id="MBTR.__init__"><a class="viewcode-back" href="../../../tutorials/mbtr.html#dscribe.descriptors.mbtr.MBTR.__init__">[docs]</a>    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span>
            <span class="bp">self</span><span class="p">,</span>
            <span class="n">species</span><span class="p">,</span>
            <span class="n">periodic</span><span class="p">,</span>
            <span class="n">k1</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
            <span class="n">k2</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
            <span class="n">k3</span><span class="o">=</span><span class="kc">None</span><span class="p">,</span>
            <span class="n">normalize_gaussians</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
            <span class="n">normalization</span><span class="o">=</span><span class="s2">&quot;none&quot;</span><span class="p">,</span>
            <span class="n">flatten</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
            <span class="n">sparse</span><span class="o">=</span><span class="kc">False</span>
            <span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;</span>
<span class="sd">        Args:</span>
<span class="sd">            species (iterable): The chemical species as a list of atomic</span>
<span class="sd">                numbers or as a list of chemical symbols. Notice that this is not</span>
<span class="sd">                the atomic numbers that are present for an individual system, but</span>
<span class="sd">                should contain all the elements that are ever going to be</span>
<span class="sd">                encountered when creating the descriptors for a set of systems.</span>
<span class="sd">                Keeping the number of chemical speices as low as possible is</span>
<span class="sd">                preferable.</span>
<span class="sd">            periodic (bool): Determines whether the system is considered to be</span>
<span class="sd">                periodic.</span>
<span class="sd">            k1 (dict): Setup for the k=1 term. For example::</span>

<span class="sd">                k1 = {</span>
<span class="sd">                    &quot;geometry&quot;: {&quot;function&quot;: &quot;atomic_number&quot;},</span>
<span class="sd">                    &quot;grid&quot;: {&quot;min&quot;: 1, &quot;max&quot;: 10, &quot;sigma&quot;: 0.1, &quot;n&quot;: 50}</span>
<span class="sd">                }</span>

<span class="sd">            k2 (dict): Dictionary containing the setup for the k=2 term.</span>
<span class="sd">                Contains setup for the used geometry function, discretization and</span>
<span class="sd">                weighting function. For example::</span>

<span class="sd">                    k2 = {</span>
<span class="sd">                        &quot;geometry&quot;: {&quot;function&quot;: &quot;inverse_distance&quot;},</span>
<span class="sd">                        &quot;grid&quot;: {&quot;min&quot;: 0.1, &quot;max&quot;: 2, &quot;sigma&quot;: 0.1, &quot;n&quot;: 50},</span>
<span class="sd">                        &quot;weighting&quot;: {&quot;function&quot;: &quot;exp&quot;, &quot;scale&quot;: 0.75, &quot;cutoff&quot;: 1e-2}</span>
<span class="sd">                    }</span>

<span class="sd">            k3 (dict): Dictionary containing the setup for the k=3 term.</span>
<span class="sd">                Contains setup for the used geometry function, discretization and</span>
<span class="sd">                weighting function. For example::</span>

<span class="sd">                    k3 = {</span>
<span class="sd">                        &quot;geometry&quot;: {&quot;function&quot;: &quot;angle&quot;},</span>
<span class="sd">                        &quot;grid&quot;: {&quot;min&quot;: 0, &quot;max&quot;: 180, &quot;sigma&quot;: 5, &quot;n&quot;: 50},</span>
<span class="sd">                        &quot;weighting&quot; = {&quot;function&quot;: &quot;exp&quot;, &quot;scale&quot;: 0.5, &quot;cutoff&quot;: 1e-3}</span>
<span class="sd">                    }</span>

<span class="sd">            normalize_gaussians (bool): Determines whether the gaussians are</span>
<span class="sd">                normalized to an area of 1. Defaults to True. If False, the</span>
<span class="sd">                normalization factor is dropped and the gaussians have the form.</span>
<span class="sd">                :math:`e^{-(x-\mu)^2/2\sigma^2}`</span>
<span class="sd">            normalization (str): Determines the method for normalizing the</span>
<span class="sd">                output. The available options are:</span>

<span class="sd">                * &quot;none&quot;: No normalization.</span>
<span class="sd">                * &quot;l2_each&quot;: Normalize the Euclidean length of each k-term</span>
<span class="sd">                  individually to unity.</span>
<span class="sd">                * &quot;n_atoms&quot;: Normalize the output by dividing it with the number</span>
<span class="sd">                  of atoms in the system. If the system is periodic, the number</span>
<span class="sd">                  of atoms is determined from the given unit cell.</span>

<span class="sd">            flatten (bool): Whether the output should be flattened to a 1D</span>
<span class="sd">                array. If False, a dictionary of the different tensors is</span>
<span class="sd">                provided, containing the values under keys: &quot;k1&quot;, &quot;k2&quot;, and</span>
<span class="sd">                &quot;k3&quot;:</span>
<span class="sd">            sparse (bool): Whether the output should be a sparse matrix or a</span>
<span class="sd">                dense numpy array.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="k">if</span> <span class="n">sparse</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">flatten</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                <span class="s2">&quot;Cannot provide a non-flattened output in sparse output because&quot;</span>
                <span class="s2">&quot; only 2D sparse matrices are supported. If you want a &quot;</span>
                <span class="s2">&quot;non-flattened output, please specify sparse=False in the MBTR&quot;</span>
                <span class="s2">&quot;constructor.&quot;</span>
            <span class="p">)</span>
        <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="n">flatten</span><span class="p">,</span> <span class="n">sparse</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">system</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">k1</span> <span class="o">=</span> <span class="n">k1</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">k2</span> <span class="o">=</span> <span class="n">k2</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">k3</span> <span class="o">=</span> <span class="n">k3</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">periodic</span> <span class="o">=</span> <span class="n">periodic</span>

        <span class="c1"># Setup the involved chemical species</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">species</span> <span class="o">=</span> <span class="n">species</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">normalization</span> <span class="o">=</span> <span class="n">normalization</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">normalize_gaussians</span> <span class="o">=</span> <span class="n">normalize_gaussians</span>

        <span class="c1"># Initializing .create() level variables</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_interaction_limit</span> <span class="o">=</span> <span class="kc">None</span>

        <span class="c1"># Check that weighting function is specified for periodic systems</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">periodic</span><span class="p">:</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">k2</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">valid</span> <span class="o">=</span> <span class="kc">False</span>
                <span class="n">weighting</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k2</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;weighting&quot;</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">weighting</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                    <span class="n">function</span> <span class="o">=</span> <span class="n">weighting</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;function&quot;</span><span class="p">)</span>
                    <span class="k">if</span> <span class="n">function</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                        <span class="k">if</span> <span class="n">function</span> <span class="o">!=</span> <span class="s2">&quot;unity&quot;</span><span class="p">:</span>
                            <span class="n">valid</span> <span class="o">=</span> <span class="kc">True</span>
                <span class="k">if</span> <span class="ow">not</span> <span class="n">valid</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                        <span class="s2">&quot;Periodic systems need to have a weighting function.&quot;</span>
                    <span class="p">)</span>

            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">k3</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">valid</span> <span class="o">=</span> <span class="kc">False</span>
                <span class="n">weighting</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k3</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;weighting&quot;</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">weighting</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                    <span class="n">function</span> <span class="o">=</span> <span class="n">weighting</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;function&quot;</span><span class="p">)</span>
                    <span class="k">if</span> <span class="n">function</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                        <span class="k">if</span> <span class="n">function</span> <span class="o">!=</span> <span class="s2">&quot;unity&quot;</span><span class="p">:</span>
                            <span class="n">valid</span> <span class="o">=</span> <span class="kc">True</span>

                <span class="k">if</span> <span class="ow">not</span> <span class="n">valid</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                        <span class="s2">&quot;Periodic systems need to have a weighting function.&quot;</span>
                    <span class="p">)</span></div>

<div class="viewcode-block" id="MBTR.check_grid"><a class="viewcode-back" href="../../../doc/dscribe.descriptors.html#dscribe.descriptors.mbtr.MBTR.check_grid">[docs]</a>    <span class="k">def</span> <span class="nf">check_grid</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">grid</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Used to ensure that the given grid settings are valid.</span>

<span class="sd">        Args:</span>
<span class="sd">            grid(dict): Dictionary containing the grid setup.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">msg</span> <span class="o">=</span> <span class="s2">&quot;The grid information is missing the value for </span><span class="si">{}</span><span class="s2">&quot;</span>
        <span class="n">val_names</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;min&quot;</span><span class="p">,</span> <span class="s2">&quot;max&quot;</span><span class="p">,</span> <span class="s2">&quot;sigma&quot;</span><span class="p">,</span> <span class="s2">&quot;n&quot;</span><span class="p">]</span>
        <span class="k">for</span> <span class="n">val_name</span> <span class="ow">in</span> <span class="n">val_names</span><span class="p">:</span>
            <span class="k">try</span><span class="p">:</span>
                <span class="n">grid</span><span class="p">[</span><span class="n">val_name</span><span class="p">]</span>
            <span class="k">except</span> <span class="ne">Exception</span><span class="p">:</span>
                <span class="k">raise</span> <span class="ne">KeyError</span><span class="p">(</span><span class="n">msg</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">val_name</span><span class="p">))</span>

        <span class="c1"># Make the n into integer</span>
        <span class="n">grid</span><span class="p">[</span><span class="s2">&quot;n&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">grid</span><span class="p">[</span><span class="s2">&quot;n&quot;</span><span class="p">])</span>
        <span class="k">if</span> <span class="n">grid</span><span class="p">[</span><span class="s2">&quot;min&quot;</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="n">grid</span><span class="p">[</span><span class="s2">&quot;max&quot;</span><span class="p">]:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                <span class="s2">&quot;The min value should be smaller than the max value.&quot;</span>
            <span class="p">)</span></div>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">k1</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_k1</span>

    <span class="nd">@k1</span><span class="o">.</span><span class="n">setter</span>
    <span class="k">def</span> <span class="nf">k1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>

            <span class="c1"># Check that only valid keys are used in the setups</span>
            <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">value</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
                <span class="n">valid_keys</span> <span class="o">=</span> <span class="nb">set</span><span class="p">((</span><span class="s2">&quot;geometry&quot;</span><span class="p">,</span> <span class="s2">&quot;grid&quot;</span><span class="p">,</span> <span class="s2">&quot;weighting&quot;</span><span class="p">))</span>
                <span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">valid_keys</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;The given setup contains the following invalid key: </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">))</span>

            <span class="c1"># Check the geometry function</span>
            <span class="n">geom_func</span> <span class="o">=</span> <span class="n">value</span><span class="p">[</span><span class="s2">&quot;geometry&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;function&quot;</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">geom_func</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">valid_geom_func</span> <span class="o">=</span> <span class="nb">set</span><span class="p">((</span><span class="s2">&quot;atomic_number&quot;</span><span class="p">,))</span>
                <span class="k">if</span> <span class="n">geom_func</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">valid_geom_func</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                        <span class="s2">&quot;Unknown geometry function specified for k=1. Please use one of&quot;</span>
                        <span class="s2">&quot; the following: </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">valid_geom_func</span><span class="p">)</span>
                    <span class="p">)</span>

            <span class="c1"># Check the weighting function</span>
            <span class="n">weighting</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;weighting&quot;</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">weighting</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">valid_weight_func</span> <span class="o">=</span> <span class="nb">set</span><span class="p">((</span><span class="s2">&quot;unity&quot;</span><span class="p">,))</span>
                <span class="n">weight_func</span> <span class="o">=</span> <span class="n">weighting</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;function&quot;</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">weight_func</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">valid_weight_func</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                        <span class="s2">&quot;Unknown weighting function specified for k=1. Please use one of&quot;</span>
                        <span class="s2">&quot; the following: </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">valid_weight_func</span><span class="p">)</span>
                    <span class="p">)</span>

            <span class="c1"># Check grid</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">check_grid</span><span class="p">(</span><span class="n">value</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">])</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_k1</span> <span class="o">=</span> <span class="n">value</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">k2</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_k2</span>

    <span class="nd">@k2</span><span class="o">.</span><span class="n">setter</span>
    <span class="k">def</span> <span class="nf">k2</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>

            <span class="c1"># Check that only valid keys are used in the setups</span>
            <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">value</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
                <span class="n">valid_keys</span> <span class="o">=</span> <span class="nb">set</span><span class="p">((</span><span class="s2">&quot;geometry&quot;</span><span class="p">,</span> <span class="s2">&quot;grid&quot;</span><span class="p">,</span> <span class="s2">&quot;weighting&quot;</span><span class="p">))</span>
                <span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">valid_keys</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;The given setup contains the following invalid key: </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">))</span>

            <span class="c1"># Check the geometry function</span>
            <span class="n">geom_func</span> <span class="o">=</span> <span class="n">value</span><span class="p">[</span><span class="s2">&quot;geometry&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;function&quot;</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">geom_func</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">valid_geom_func</span> <span class="o">=</span> <span class="nb">set</span><span class="p">((</span><span class="s2">&quot;distance&quot;</span><span class="p">,</span> <span class="s2">&quot;inverse_distance&quot;</span><span class="p">))</span>
                <span class="k">if</span> <span class="n">geom_func</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">valid_geom_func</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                        <span class="s2">&quot;Unknown geometry function specified for k=2. Please use one of&quot;</span>
                        <span class="s2">&quot; the following: </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">valid_geom_func</span><span class="p">)</span>
                    <span class="p">)</span>

            <span class="c1"># Check the weighting function</span>
            <span class="n">weighting</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;weighting&quot;</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">weighting</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">valid_weight_func</span> <span class="o">=</span> <span class="nb">set</span><span class="p">((</span><span class="s2">&quot;unity&quot;</span><span class="p">,</span> <span class="s2">&quot;exponential&quot;</span><span class="p">,</span> <span class="s2">&quot;exp&quot;</span><span class="p">))</span>
                <span class="n">weight_func</span> <span class="o">=</span> <span class="n">weighting</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;function&quot;</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">weight_func</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">valid_weight_func</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                        <span class="s2">&quot;Unknown weighting function specified for k=2. Please use one of&quot;</span>
                        <span class="s2">&quot; the following: </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">valid_weight_func</span><span class="p">)</span>
                    <span class="p">)</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="k">if</span> <span class="n">weight_func</span> <span class="o">==</span> <span class="s2">&quot;exponential&quot;</span> <span class="ow">or</span> <span class="n">weight_func</span> <span class="o">==</span> <span class="s2">&quot;exp&quot;</span><span class="p">:</span>
                        <span class="n">needed</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;cutoff&quot;</span><span class="p">,</span> <span class="s2">&quot;scale&quot;</span><span class="p">)</span>
                        <span class="k">for</span> <span class="n">pname</span> <span class="ow">in</span> <span class="n">needed</span><span class="p">:</span>
                            <span class="n">param</span> <span class="o">=</span> <span class="n">weighting</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">pname</span><span class="p">)</span>
                            <span class="k">if</span> <span class="n">param</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                                    <span class="s2">&quot;Missing value for &#39;</span><span class="si">{}</span><span class="s2">&#39; in the k=2 weighting.&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
                                <span class="p">)</span>

            <span class="c1"># Check grid</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">check_grid</span><span class="p">(</span><span class="n">value</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">])</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_k2</span> <span class="o">=</span> <span class="n">value</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">k3</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_k3</span>

    <span class="nd">@k3</span><span class="o">.</span><span class="n">setter</span>
    <span class="k">def</span> <span class="nf">k3</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">value</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>

            <span class="c1"># Check that only valid keys are used in the setups</span>
            <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="n">value</span><span class="o">.</span><span class="n">keys</span><span class="p">():</span>
                <span class="n">valid_keys</span> <span class="o">=</span> <span class="nb">set</span><span class="p">((</span><span class="s2">&quot;geometry&quot;</span><span class="p">,</span> <span class="s2">&quot;grid&quot;</span><span class="p">,</span> <span class="s2">&quot;weighting&quot;</span><span class="p">))</span>
                <span class="k">if</span> <span class="n">key</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">valid_keys</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;The given setup contains the following invalid key: </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">))</span>

            <span class="c1"># Check the geometry function</span>
            <span class="n">geom_func</span> <span class="o">=</span> <span class="n">value</span><span class="p">[</span><span class="s2">&quot;geometry&quot;</span><span class="p">]</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;function&quot;</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">geom_func</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">valid_geom_func</span> <span class="o">=</span> <span class="nb">set</span><span class="p">((</span><span class="s2">&quot;angle&quot;</span><span class="p">,</span> <span class="s2">&quot;cosine&quot;</span><span class="p">))</span>
                <span class="k">if</span> <span class="n">geom_func</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">valid_geom_func</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                        <span class="s2">&quot;Unknown geometry function specified for k=2. Please use one of&quot;</span>
                        <span class="s2">&quot; the following: </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">valid_geom_func</span><span class="p">)</span>
                    <span class="p">)</span>

            <span class="c1"># Check the weighting function</span>
            <span class="n">weighting</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;weighting&quot;</span><span class="p">)</span>
            <span class="k">if</span> <span class="n">weighting</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">valid_weight_func</span> <span class="o">=</span> <span class="nb">set</span><span class="p">((</span><span class="s2">&quot;unity&quot;</span><span class="p">,</span> <span class="s2">&quot;exponential&quot;</span><span class="p">,</span> <span class="s2">&quot;exp&quot;</span><span class="p">))</span>
                <span class="n">weight_func</span> <span class="o">=</span> <span class="n">weighting</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;function&quot;</span><span class="p">)</span>
                <span class="k">if</span> <span class="n">weight_func</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">valid_weight_func</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                        <span class="s2">&quot;Unknown weighting function specified for k=2. Please use one of&quot;</span>
                        <span class="s2">&quot; the following: </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">valid_weight_func</span><span class="p">)</span>
                    <span class="p">)</span>
                <span class="k">else</span><span class="p">:</span>
                    <span class="k">if</span> <span class="n">weight_func</span> <span class="o">==</span> <span class="s2">&quot;exponential&quot;</span> <span class="ow">or</span> <span class="n">weight_func</span> <span class="o">==</span> <span class="s2">&quot;exp&quot;</span><span class="p">:</span>
                        <span class="n">needed</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;cutoff&quot;</span><span class="p">,</span> <span class="s2">&quot;scale&quot;</span><span class="p">)</span>
                        <span class="k">for</span> <span class="n">pname</span> <span class="ow">in</span> <span class="n">needed</span><span class="p">:</span>
                            <span class="n">param</span> <span class="o">=</span> <span class="n">weighting</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">pname</span><span class="p">)</span>
                            <span class="k">if</span> <span class="n">param</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
                                <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                                    <span class="s2">&quot;Missing value for &#39;</span><span class="si">{}</span><span class="s2">&#39; in the k=3 weighting.&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>
                                <span class="p">)</span>

            <span class="c1"># Check grid</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">check_grid</span><span class="p">(</span><span class="n">value</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">])</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_k3</span> <span class="o">=</span> <span class="n">value</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">species</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_species</span>

    <span class="nd">@species</span><span class="o">.</span><span class="n">setter</span>
    <span class="k">def</span> <span class="nf">species</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Used to check the validity of given atomic numbers and to initialize</span>
<span class="sd">        the C-memory layout for them.</span>

<span class="sd">        Args:</span>
<span class="sd">            value(iterable): Chemical species either as a list of atomic</span>
<span class="sd">                numbers or list of chemical symbols.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="c1"># The species are stored as atomic numbers for internal use.</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_set_species</span><span class="p">(</span><span class="n">value</span><span class="p">)</span>

        <span class="c1"># Setup mappings between atom indices and types together with some</span>
        <span class="c1"># statistics</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">atomic_number_to_index</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">index_to_atomic_number</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="k">for</span> <span class="n">i_atom</span><span class="p">,</span> <span class="n">atomic_number</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_atomic_numbers</span><span class="p">):</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">atomic_number_to_index</span><span class="p">[</span><span class="n">atomic_number</span><span class="p">]</span> <span class="o">=</span> <span class="n">i_atom</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">index_to_atomic_number</span><span class="p">[</span><span class="n">i_atom</span><span class="p">]</span> <span class="o">=</span> <span class="n">atomic_number</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">n_elements</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_atomic_numbers</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">max_atomic_number</span> <span class="o">=</span> <span class="nb">max</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_atomic_numbers</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">min_atomic_number</span> <span class="o">=</span> <span class="nb">min</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">_atomic_numbers</span><span class="p">)</span>

    <span class="nd">@property</span>
    <span class="k">def</span> <span class="nf">normalization</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">_normalization</span>

    <span class="nd">@normalization</span><span class="o">.</span><span class="n">setter</span>
    <span class="k">def</span> <span class="nf">normalization</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">value</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Checks that the given normalization is valid.</span>

<span class="sd">        Args:</span>
<span class="sd">            value(str): The normalization method to use.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">norm_options</span> <span class="o">=</span> <span class="nb">set</span><span class="p">((</span><span class="s2">&quot;l2_each&quot;</span><span class="p">,</span> <span class="s2">&quot;none&quot;</span><span class="p">,</span> <span class="s2">&quot;n_atoms&quot;</span><span class="p">))</span>
        <span class="k">if</span> <span class="n">value</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">norm_options</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                <span class="s2">&quot;Unknown normalization option given. Please use one of the &quot;</span>
                <span class="s2">&quot;following: </span><span class="si">{}</span><span class="s2">.&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="s2">&quot;, &quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="nb">str</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">norm_options</span><span class="p">]))</span>
            <span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_normalization</span> <span class="o">=</span> <span class="n">value</span>

<div class="viewcode-block" id="MBTR.get_k1_axis"><a class="viewcode-back" href="../../../doc/dscribe.descriptors.html#dscribe.descriptors.mbtr.MBTR.get_k1_axis">[docs]</a>    <span class="k">def</span> <span class="nf">get_k1_axis</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Used to get the discretized axis for geometry function of the k=1</span>
<span class="sd">        term.</span>

<span class="sd">        Returns:</span>
<span class="sd">            np.ndarray: The discretized axis for the k=1 term.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">start</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k1</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">][</span><span class="s2">&quot;min&quot;</span><span class="p">]</span>
        <span class="n">stop</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k1</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">][</span><span class="s2">&quot;max&quot;</span><span class="p">]</span>
        <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k1</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">][</span><span class="s2">&quot;n&quot;</span><span class="p">]</span>

        <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="n">start</span><span class="p">,</span> <span class="n">stop</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span></div>

<div class="viewcode-block" id="MBTR.get_k2_axis"><a class="viewcode-back" href="../../../doc/dscribe.descriptors.html#dscribe.descriptors.mbtr.MBTR.get_k2_axis">[docs]</a>    <span class="k">def</span> <span class="nf">get_k2_axis</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Used to get the discretized axis for geometry function of the k=2</span>
<span class="sd">        term.</span>

<span class="sd">        Returns:</span>
<span class="sd">            np.ndarray: The discretized axis for the k=2 term.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">start</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k2</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">][</span><span class="s2">&quot;min&quot;</span><span class="p">]</span>
        <span class="n">stop</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k2</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">][</span><span class="s2">&quot;max&quot;</span><span class="p">]</span>
        <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k2</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">][</span><span class="s2">&quot;n&quot;</span><span class="p">]</span>

        <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="n">start</span><span class="p">,</span> <span class="n">stop</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span></div>

<div class="viewcode-block" id="MBTR.get_k3_axis"><a class="viewcode-back" href="../../../doc/dscribe.descriptors.html#dscribe.descriptors.mbtr.MBTR.get_k3_axis">[docs]</a>    <span class="k">def</span> <span class="nf">get_k3_axis</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Used to get the discretized axis for geometry function of the k=3</span>
<span class="sd">        term.</span>

<span class="sd">        Returns:</span>
<span class="sd">            np.ndarray: The discretized axis for the k=3 term.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">start</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k3</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">][</span><span class="s2">&quot;min&quot;</span><span class="p">]</span>
        <span class="n">stop</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k3</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">][</span><span class="s2">&quot;max&quot;</span><span class="p">]</span>
        <span class="n">n</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k3</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">][</span><span class="s2">&quot;n&quot;</span><span class="p">]</span>

        <span class="k">return</span> <span class="n">np</span><span class="o">.</span><span class="n">linspace</span><span class="p">(</span><span class="n">start</span><span class="p">,</span> <span class="n">stop</span><span class="p">,</span> <span class="n">n</span><span class="p">)</span></div>

<div class="viewcode-block" id="MBTR.create"><a class="viewcode-back" href="../../../tutorials/mbtr.html#dscribe.descriptors.mbtr.MBTR.create">[docs]</a>    <span class="k">def</span> <span class="nf">create</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">system</span><span class="p">,</span> <span class="n">n_jobs</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">verbose</span><span class="o">=</span><span class="kc">False</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Return MBTR output for the given systems.</span>

<span class="sd">        Args:</span>
<span class="sd">            system (:class:`ase.Atoms` or list of :class:`ase.Atoms`): One or many atomic structures.</span>
<span class="sd">            n_jobs (int): Number of parallel jobs to instantiate. Parallellizes</span>
<span class="sd">                the calculation across samples. Defaults to serial calculation</span>
<span class="sd">                with n_jobs=1.</span>
<span class="sd">            verbose(bool): Controls whether to print the progress of each job</span>
<span class="sd">                into to the console.</span>

<span class="sd">        Returns:</span>
<span class="sd">            np.ndarray | scipy.sparse.csr_matrix | list: MBTR for the</span>
<span class="sd">            given systems. The return type depends on the &#39;sparse&#39; and</span>
<span class="sd">            &#39;flatten&#39;-attributes. For flattened output a single numpy array or</span>
<span class="sd">            sparse scipy.csr_matrix is returned. The first dimension is</span>
<span class="sd">            determined by the amount of systems. If the output is not</span>
<span class="sd">            flattened, dictionaries containing the MBTR tensors for each k-term</span>
<span class="sd">            are returned.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="c1"># If single system given, skip the parallelization</span>
        <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">system</span><span class="p">,</span> <span class="p">(</span><span class="n">Atoms</span><span class="p">,</span> <span class="n">System</span><span class="p">)):</span>
            <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">create_single</span><span class="p">(</span><span class="n">system</span><span class="p">)</span>

        <span class="c1"># Combine input arguments</span>
        <span class="n">inp</span> <span class="o">=</span> <span class="p">[(</span><span class="n">i_sys</span><span class="p">,)</span> <span class="k">for</span> <span class="n">i_sys</span> <span class="ow">in</span> <span class="n">system</span><span class="p">]</span>

        <span class="c1"># Here we precalculate the size for each job to preallocate memory.</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">flatten</span><span class="p">:</span>
            <span class="n">n_samples</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">system</span><span class="p">)</span>
            <span class="n">k</span><span class="p">,</span> <span class="n">m</span> <span class="o">=</span> <span class="nb">divmod</span><span class="p">(</span><span class="n">n_samples</span><span class="p">,</span> <span class="n">n_jobs</span><span class="p">)</span>
            <span class="n">jobs</span> <span class="o">=</span> <span class="p">(</span><span class="n">inp</span><span class="p">[</span><span class="n">i</span> <span class="o">*</span> <span class="n">k</span> <span class="o">+</span> <span class="nb">min</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">m</span><span class="p">):(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="n">k</span> <span class="o">+</span> <span class="nb">min</span><span class="p">(</span><span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">m</span><span class="p">)]</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">n_jobs</span><span class="p">))</span>
            <span class="n">output_sizes</span> <span class="o">=</span> <span class="p">[</span><span class="nb">len</span><span class="p">(</span><span class="n">job</span><span class="p">)</span> <span class="k">for</span> <span class="n">job</span> <span class="ow">in</span> <span class="n">jobs</span><span class="p">]</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">output_sizes</span> <span class="o">=</span> <span class="kc">None</span>

        <span class="c1"># Create in parallel</span>
        <span class="n">output</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">create_parallel</span><span class="p">(</span><span class="n">inp</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">create_single</span><span class="p">,</span> <span class="n">n_jobs</span><span class="p">,</span> <span class="n">output_sizes</span><span class="p">,</span> <span class="n">verbose</span><span class="o">=</span><span class="n">verbose</span><span class="p">)</span>

        <span class="k">return</span> <span class="n">output</span></div>

<div class="viewcode-block" id="MBTR.create_single"><a class="viewcode-back" href="../../../doc/dscribe.descriptors.html#dscribe.descriptors.mbtr.MBTR.create_single">[docs]</a>    <span class="k">def</span> <span class="nf">create_single</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">system</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Return the many-body tensor representation for the given system.</span>

<span class="sd">        Args:</span>
<span class="sd">            system (:class:`ase.Atoms` | :class:`.System`): Input system.</span>

<span class="sd">        Returns:</span>
<span class="sd">            dict | np.ndarray | scipy.sparse.coo_matrix: The return type is</span>
<span class="sd">            specified by the &#39;flatten&#39; and &#39;sparse&#39;-parameters. If the output</span>
<span class="sd">            is not flattened, a dictionary containing of MBTR outputs as numpy</span>
<span class="sd">            arrays is created. Each output is under a &quot;kX&quot; key. If the output</span>
<span class="sd">            is flattened, a single concatenated output vector is returned,</span>
<span class="sd">            either as a sparse or a dense vector.</span>
<span class="sd">       &quot;&quot;&quot;</span>
        <span class="c1"># Transform the input system into the internal System-object</span>
        <span class="n">system</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_system</span><span class="p">(</span><span class="n">system</span><span class="p">)</span>

        <span class="c1"># Ensuring variables are re-initialized when a new system is introduced</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">system</span> <span class="o">=</span> <span class="n">system</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">_interaction_limit</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">system</span><span class="p">)</span>

        <span class="c1"># Check that the system does not have elements that are not in the list</span>
        <span class="c1"># of atomic numbers</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">check_atomic_numbers</span><span class="p">(</span><span class="n">system</span><span class="o">.</span><span class="n">get_atomic_numbers</span><span class="p">())</span>

        <span class="n">mbtr</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">k1</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">mbtr</span><span class="p">[</span><span class="s2">&quot;k1&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_k1</span><span class="p">(</span><span class="n">system</span><span class="p">)</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">k2</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">mbtr</span><span class="p">[</span><span class="s2">&quot;k2&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_k2</span><span class="p">(</span><span class="n">system</span><span class="p">)</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">k3</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">mbtr</span><span class="p">[</span><span class="s2">&quot;k3&quot;</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">_get_k3</span><span class="p">(</span><span class="n">system</span><span class="p">)</span>

        <span class="c1"># Handle normalization</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">normalization</span> <span class="o">==</span> <span class="s2">&quot;l2_each&quot;</span><span class="p">:</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">flatten</span> <span class="ow">is</span> <span class="kc">True</span><span class="p">:</span>
                <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">mbtr</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
                    <span class="n">i_data</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">array</span><span class="p">(</span><span class="n">value</span><span class="o">.</span><span class="n">tocsr</span><span class="p">()</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>
                    <span class="n">i_norm</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">norm</span><span class="p">(</span><span class="n">i_data</span><span class="p">)</span>
                    <span class="n">mbtr</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span><span class="o">/</span><span class="n">i_norm</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">mbtr</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
                    <span class="n">i_data</span> <span class="o">=</span> <span class="n">value</span><span class="o">.</span><span class="n">ravel</span><span class="p">()</span>
                    <span class="n">i_norm</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">linalg</span><span class="o">.</span><span class="n">norm</span><span class="p">(</span><span class="n">i_data</span><span class="p">)</span>
                    <span class="n">mbtr</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span><span class="o">/</span><span class="n">i_norm</span>
        <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span><span class="n">normalization</span> <span class="o">==</span> <span class="s2">&quot;n_atoms&quot;</span><span class="p">:</span>
            <span class="n">n_atoms</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">system</span><span class="p">)</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">flatten</span> <span class="ow">is</span> <span class="kc">True</span><span class="p">:</span>
                <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">mbtr</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
                    <span class="n">mbtr</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span><span class="o">/</span><span class="n">n_atoms</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">value</span> <span class="ow">in</span> <span class="n">mbtr</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
                    <span class="n">mbtr</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="n">value</span><span class="o">/</span><span class="n">n_atoms</span>

        <span class="c1"># Flatten output if requested</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">flatten</span><span class="p">:</span>
            <span class="n">length</span> <span class="o">=</span> <span class="mi">0</span>

            <span class="n">datas</span> <span class="o">=</span> <span class="p">[]</span>
            <span class="n">rows</span> <span class="o">=</span> <span class="p">[]</span>
            <span class="n">cols</span> <span class="o">=</span> <span class="p">[]</span>
            <span class="k">for</span> <span class="n">key</span> <span class="ow">in</span> <span class="nb">sorted</span><span class="p">(</span><span class="n">mbtr</span><span class="o">.</span><span class="n">keys</span><span class="p">()):</span>
                <span class="n">tensor</span> <span class="o">=</span> <span class="n">mbtr</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
                <span class="n">size</span> <span class="o">=</span> <span class="n">tensor</span><span class="o">.</span><span class="n">shape</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
                <span class="n">coo</span> <span class="o">=</span> <span class="n">tensor</span><span class="o">.</span><span class="n">tocoo</span><span class="p">()</span>
                <span class="n">datas</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">coo</span><span class="o">.</span><span class="n">data</span><span class="p">)</span>
                <span class="n">rows</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">coo</span><span class="o">.</span><span class="n">row</span><span class="p">)</span>
                <span class="n">cols</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">coo</span><span class="o">.</span><span class="n">col</span> <span class="o">+</span> <span class="n">length</span><span class="p">)</span>
                <span class="n">length</span> <span class="o">+=</span> <span class="n">size</span>

            <span class="n">datas</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">concatenate</span><span class="p">(</span><span class="n">datas</span><span class="p">)</span>
            <span class="n">rows</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">concatenate</span><span class="p">(</span><span class="n">rows</span><span class="p">)</span>
            <span class="n">cols</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">concatenate</span><span class="p">(</span><span class="n">cols</span><span class="p">)</span>
            <span class="n">mbtr</span> <span class="o">=</span> <span class="n">coo_matrix</span><span class="p">((</span><span class="n">datas</span><span class="p">,</span> <span class="p">(</span><span class="n">rows</span><span class="p">,</span> <span class="n">cols</span><span class="p">)),</span> <span class="n">shape</span><span class="o">=</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="n">length</span><span class="p">],</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">float32</span><span class="p">)</span>

            <span class="c1"># Make into a dense array if requested</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">sparse</span><span class="p">:</span>
                <span class="n">mbtr</span> <span class="o">=</span> <span class="n">mbtr</span><span class="o">.</span><span class="n">toarray</span><span class="p">()</span>

        <span class="k">return</span> <span class="n">mbtr</span></div>

<div class="viewcode-block" id="MBTR.get_number_of_features"><a class="viewcode-back" href="../../../doc/dscribe.descriptors.html#dscribe.descriptors.mbtr.MBTR.get_number_of_features">[docs]</a>    <span class="k">def</span> <span class="nf">get_number_of_features</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Used to inquire the final number of features that this descriptor</span>
<span class="sd">        will have.</span>

<span class="sd">        Returns:</span>
<span class="sd">            int: Number of features for this descriptor.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">n_features</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="n">n_elem</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">n_elements</span>

        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">k1</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">n_k1_grid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k1</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">][</span><span class="s2">&quot;n&quot;</span><span class="p">]</span>
            <span class="n">n_k1</span> <span class="o">=</span> <span class="n">n_elem</span><span class="o">*</span><span class="n">n_k1_grid</span>
            <span class="n">n_features</span> <span class="o">+=</span> <span class="n">n_k1</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">k2</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">n_k2_grid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k2</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">][</span><span class="s2">&quot;n&quot;</span><span class="p">]</span>
            <span class="n">n_k2</span> <span class="o">=</span> <span class="p">(</span><span class="n">n_elem</span><span class="o">*</span><span class="p">(</span><span class="n">n_elem</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span><span class="o">*</span><span class="n">n_k2_grid</span>
            <span class="n">n_features</span> <span class="o">+=</span> <span class="n">n_k2</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">k3</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">n_k3_grid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k3</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">][</span><span class="s2">&quot;n&quot;</span><span class="p">]</span>
            <span class="n">n_k3</span> <span class="o">=</span> <span class="p">(</span><span class="n">n_elem</span><span class="o">*</span><span class="n">n_elem</span><span class="o">*</span><span class="p">(</span><span class="n">n_elem</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span><span class="o">*</span><span class="n">n_k3_grid</span>
            <span class="n">n_features</span> <span class="o">+=</span> <span class="n">n_k3</span>

        <span class="k">return</span> <span class="nb">int</span><span class="p">(</span><span class="n">n_features</span><span class="p">)</span></div>

<div class="viewcode-block" id="MBTR.get_location"><a class="viewcode-back" href="../../../doc/dscribe.descriptors.html#dscribe.descriptors.mbtr.MBTR.get_location">[docs]</a>    <span class="k">def</span> <span class="nf">get_location</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">species</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Can be used to query the location of a species combination in the</span>
<span class="sd">        the flattened output.</span>

<span class="sd">        Args:</span>
<span class="sd">            species(tuple): A tuple containing a species combination as</span>
<span class="sd">            chemical symbols or atomic numbers. The tuple can be for example</span>
<span class="sd">            (&quot;H&quot;), (&quot;H&quot;, &quot;O&quot;) or (&quot;H&quot;, &quot;O&quot;, &quot;H&quot;).</span>

<span class="sd">        Returns:</span>
<span class="sd">            slice: slice containing the location of the specified species</span>
<span class="sd">            combination. The location is given as a python slice-object, that</span>
<span class="sd">            can be directly used to target ranges in the output.</span>

<span class="sd">        Raises:</span>
<span class="sd">            ValueError: If the requested species combination is not in the</span>
<span class="sd">            output or if invalid species defined.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="c1"># Check that the corresponding part is calculated</span>
        <span class="n">k</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">species</span><span class="p">)</span>
        <span class="n">term</span> <span class="o">=</span> <span class="nb">getattr</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="s2">&quot;k</span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">k</span><span class="p">))</span>
        <span class="k">if</span> <span class="n">term</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
            <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
                <span class="s2">&quot;Cannot retrieve the location for </span><span class="si">{}</span><span class="s2">, as the term k</span><span class="si">{}</span><span class="s2"> has not &quot;</span>
                <span class="s2">&quot;been specied.&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">species</span><span class="p">,</span> <span class="n">k</span><span class="p">)</span>
            <span class="p">)</span>

        <span class="c1"># Change chemical elements into atomic numbers</span>
        <span class="n">numbers</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">specie</span> <span class="ow">in</span> <span class="n">species</span><span class="p">:</span>
            <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">specie</span><span class="p">,</span> <span class="nb">str</span><span class="p">):</span>
                <span class="k">try</span><span class="p">:</span>
                    <span class="n">specie</span> <span class="o">=</span> <span class="n">ase</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">atomic_numbers</span><span class="p">[</span><span class="n">specie</span><span class="p">]</span>
                <span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
                    <span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Invalid chemical species: </span><span class="si">{}</span><span class="s2">&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="n">specie</span><span class="p">))</span>
            <span class="n">numbers</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">specie</span><span class="p">)</span>

        <span class="c1"># Change into internal indexing</span>
        <span class="n">numbers</span> <span class="o">=</span> <span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">atomic_number_to_index</span><span class="p">[</span><span class="n">x</span><span class="p">]</span> <span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">numbers</span><span class="p">]</span>
        <span class="n">n_elem</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">n_elements</span>

        <span class="c1"># k=1</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">numbers</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">:</span>
            <span class="n">n1</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k1</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">][</span><span class="s2">&quot;n&quot;</span><span class="p">]</span>
            <span class="n">i</span> <span class="o">=</span> <span class="n">numbers</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
            <span class="n">m</span> <span class="o">=</span> <span class="n">i</span>
            <span class="n">start</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">m</span><span class="o">*</span><span class="n">n1</span><span class="p">)</span>
            <span class="n">end</span> <span class="o">=</span> <span class="nb">int</span><span class="p">((</span><span class="n">m</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="n">n1</span><span class="p">)</span>

        <span class="c1"># k=2</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">numbers</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">numbers</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">numbers</span><span class="p">[</span><span class="mi">1</span><span class="p">]:</span>
                <span class="n">numbers</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">reversed</span><span class="p">(</span><span class="n">numbers</span><span class="p">))</span>

            <span class="n">n2</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k2</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">][</span><span class="s2">&quot;n&quot;</span><span class="p">]</span>
            <span class="n">i</span> <span class="o">=</span> <span class="n">numbers</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
            <span class="n">j</span> <span class="o">=</span> <span class="n">numbers</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>

            <span class="c1"># This is the index of the spectrum. It is given by enumerating the</span>
            <span class="c1"># elements of an upper triangular matrix from left to right and top</span>
            <span class="c1"># to bottom.</span>
            <span class="n">m</span> <span class="o">=</span> <span class="n">j</span> <span class="o">+</span> <span class="n">i</span><span class="o">*</span><span class="n">n_elem</span> <span class="o">-</span> <span class="n">i</span><span class="o">*</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span>

            <span class="n">offset</span> <span class="o">=</span> <span class="mi">0</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">k1</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">n1</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k1</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">][</span><span class="s2">&quot;n&quot;</span><span class="p">]</span>
                <span class="n">offset</span> <span class="o">+=</span> <span class="n">n_elem</span><span class="o">*</span><span class="n">n1</span>
            <span class="n">start</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">offset</span><span class="o">+</span><span class="n">m</span><span class="o">*</span><span class="n">n2</span><span class="p">)</span>
            <span class="n">end</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">offset</span><span class="o">+</span><span class="p">(</span><span class="n">m</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="n">n2</span><span class="p">)</span>

        <span class="c1"># k=3</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">numbers</span><span class="p">)</span> <span class="o">==</span> <span class="mi">3</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">numbers</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">numbers</span><span class="p">[</span><span class="mi">2</span><span class="p">]:</span>
                <span class="n">numbers</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="nb">reversed</span><span class="p">(</span><span class="n">numbers</span><span class="p">))</span>

            <span class="n">n3</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k3</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">][</span><span class="s2">&quot;n&quot;</span><span class="p">]</span>
            <span class="n">i</span> <span class="o">=</span> <span class="n">numbers</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
            <span class="n">j</span> <span class="o">=</span> <span class="n">numbers</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
            <span class="n">k</span> <span class="o">=</span> <span class="n">numbers</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>

            <span class="c1"># This is the index of the spectrum. It is given by enumerating the</span>
            <span class="c1"># elements of a three-dimensional array where for valid elements</span>
            <span class="c1"># k&gt;=i. The enumeration begins from [0, 0, 0], and ends at [n_elem,</span>
            <span class="c1"># n_elem, n_elem], looping the elements in the order k, i, j.</span>
            <span class="n">m</span> <span class="o">=</span> <span class="n">j</span><span class="o">*</span><span class="n">n_elem</span><span class="o">*</span><span class="p">(</span><span class="n">n_elem</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span> <span class="o">+</span> <span class="n">k</span> <span class="o">+</span> <span class="n">i</span><span class="o">*</span><span class="n">n_elem</span> <span class="o">-</span> <span class="n">i</span><span class="o">*</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span>

            <span class="n">offset</span> <span class="o">=</span> <span class="mi">0</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">k1</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">n1</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k1</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">][</span><span class="s2">&quot;n&quot;</span><span class="p">]</span>
                <span class="n">offset</span> <span class="o">+=</span> <span class="n">n_elem</span><span class="o">*</span><span class="n">n1</span>
            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">k2</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
                <span class="n">n2</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k2</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">][</span><span class="s2">&quot;n&quot;</span><span class="p">]</span>
                <span class="n">offset</span> <span class="o">+=</span> <span class="p">(</span><span class="n">n_elem</span><span class="o">*</span><span class="p">(</span><span class="n">n_elem</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span><span class="o">*</span><span class="n">n2</span>
            <span class="n">start</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">offset</span><span class="o">+</span><span class="n">m</span><span class="o">*</span><span class="n">n3</span><span class="p">)</span>
            <span class="n">end</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">offset</span><span class="o">+</span><span class="p">(</span><span class="n">m</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="n">n3</span><span class="p">)</span>

        <span class="k">return</span> <span class="nb">slice</span><span class="p">(</span><span class="n">start</span><span class="p">,</span> <span class="n">end</span><span class="p">)</span></div>

    <span class="k">def</span> <span class="nf">_get_k1</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">system</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Calculates the second order terms where the scalar mapping is the</span>
<span class="sd">        inverse distance between atoms.</span>

<span class="sd">        Returns:</span>
<span class="sd">            1D ndarray: flattened K2 values.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">grid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k1</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">]</span>
        <span class="n">start</span> <span class="o">=</span> <span class="n">grid</span><span class="p">[</span><span class="s2">&quot;min&quot;</span><span class="p">]</span>
        <span class="n">stop</span> <span class="o">=</span> <span class="n">grid</span><span class="p">[</span><span class="s2">&quot;max&quot;</span><span class="p">]</span>
        <span class="n">n</span> <span class="o">=</span> <span class="n">grid</span><span class="p">[</span><span class="s2">&quot;n&quot;</span><span class="p">]</span>
        <span class="n">sigma</span> <span class="o">=</span> <span class="n">grid</span><span class="p">[</span><span class="s2">&quot;sigma&quot;</span><span class="p">]</span>

        <span class="c1"># Determine the geometry function</span>
        <span class="n">geom_func_name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k1</span><span class="p">[</span><span class="s2">&quot;geometry&quot;</span><span class="p">][</span><span class="s2">&quot;function&quot;</span><span class="p">]</span>

        <span class="n">cmbtr</span> <span class="o">=</span> <span class="n">MBTRWrapper</span><span class="p">(</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">atomic_number_to_index</span><span class="p">,</span>
            <span class="n">interaction_limit</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_interaction_limit</span><span class="p">,</span>
            <span class="n">indices</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="nb">len</span><span class="p">(</span><span class="n">system</span><span class="p">),</span> <span class="mi">3</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="nb">int</span><span class="p">)</span>
        <span class="p">)</span>

        <span class="n">k1_map</span> <span class="o">=</span> <span class="n">cmbtr</span><span class="o">.</span><span class="n">get_k1</span><span class="p">(</span>
            <span class="n">system</span><span class="o">.</span><span class="n">get_atomic_numbers</span><span class="p">(),</span>
            <span class="n">geom_func</span><span class="o">=</span><span class="n">geom_func_name</span><span class="o">.</span><span class="n">encode</span><span class="p">(),</span>
            <span class="n">weight_func</span><span class="o">=</span><span class="sa">b</span><span class="s2">&quot;unity&quot;</span><span class="p">,</span>
            <span class="n">parameters</span><span class="o">=</span><span class="p">{},</span>
            <span class="n">start</span><span class="o">=</span><span class="n">start</span><span class="p">,</span>
            <span class="n">stop</span><span class="o">=</span><span class="n">stop</span><span class="p">,</span>
            <span class="n">sigma</span><span class="o">=</span><span class="n">sigma</span><span class="p">,</span>
            <span class="n">n</span><span class="o">=</span><span class="n">n</span><span class="p">,</span>
        <span class="p">)</span>

        <span class="c1"># Depending on flattening, use either a sparse matrix or a dense one.</span>
        <span class="n">n_elem</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">n_elements</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">flatten</span><span class="p">:</span>
            <span class="n">k1</span> <span class="o">=</span> <span class="n">lil_matrix</span><span class="p">((</span><span class="mi">1</span><span class="p">,</span> <span class="n">n_elem</span><span class="o">*</span><span class="n">n</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">float32</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">k1</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">n_elem</span><span class="p">,</span> <span class="n">n</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">float32</span><span class="p">)</span>

        <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">gaussian_sum</span> <span class="ow">in</span> <span class="n">k1_map</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
            <span class="n">i</span> <span class="o">=</span> <span class="n">key</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>

            <span class="c1"># Denormalize if requested</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">normalize_gaussians</span><span class="p">:</span>
                <span class="n">max_val</span> <span class="o">=</span> <span class="mi">1</span><span class="o">/</span><span class="p">(</span><span class="n">sigma</span><span class="o">*</span><span class="n">math</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">2</span><span class="o">*</span><span class="n">math</span><span class="o">.</span><span class="n">pi</span><span class="p">))</span>
                <span class="n">gaussian_sum</span> <span class="o">/=</span> <span class="n">max_val</span>

            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">flatten</span><span class="p">:</span>
                <span class="n">start</span> <span class="o">=</span> <span class="n">i</span><span class="o">*</span><span class="n">n</span>
                <span class="n">end</span> <span class="o">=</span> <span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="n">n</span>
                <span class="n">k1</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="n">start</span><span class="p">:</span><span class="n">end</span><span class="p">]</span> <span class="o">=</span> <span class="n">gaussian_sum</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">k1</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="p">:]</span> <span class="o">=</span> <span class="n">gaussian_sum</span>

        <span class="k">return</span> <span class="n">k1</span>

    <span class="k">def</span> <span class="nf">_get_k2</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">system</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Calculates the second order terms where the scalar mapping is the</span>
<span class="sd">        inverse distance between atoms.</span>

<span class="sd">        Returns:</span>
<span class="sd">            1D ndarray: flattened K2 values.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">grid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k2</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">]</span>
        <span class="n">start</span> <span class="o">=</span> <span class="n">grid</span><span class="p">[</span><span class="s2">&quot;min&quot;</span><span class="p">]</span>
        <span class="n">stop</span> <span class="o">=</span> <span class="n">grid</span><span class="p">[</span><span class="s2">&quot;max&quot;</span><span class="p">]</span>
        <span class="n">n</span> <span class="o">=</span> <span class="n">grid</span><span class="p">[</span><span class="s2">&quot;n&quot;</span><span class="p">]</span>
        <span class="n">sigma</span> <span class="o">=</span> <span class="n">grid</span><span class="p">[</span><span class="s2">&quot;sigma&quot;</span><span class="p">]</span>
        <span class="c1"># Determine the weighting function and possible radial cutoff</span>
        <span class="n">radial_cutoff</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="n">weighting</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k2</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;weighting&quot;</span><span class="p">)</span>
        <span class="n">parameters</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="k">if</span> <span class="n">weighting</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">weighting_function</span> <span class="o">=</span> <span class="n">weighting</span><span class="p">[</span><span class="s2">&quot;function&quot;</span><span class="p">]</span>
            <span class="k">if</span> <span class="n">weighting_function</span> <span class="o">==</span> <span class="s2">&quot;exponential&quot;</span> <span class="ow">or</span> <span class="n">weighting_function</span> <span class="o">==</span> <span class="s2">&quot;exp&quot;</span><span class="p">:</span>
                <span class="n">scale</span> <span class="o">=</span> <span class="n">weighting</span><span class="p">[</span><span class="s2">&quot;scale&quot;</span><span class="p">]</span>
                <span class="n">cutoff</span> <span class="o">=</span> <span class="n">weighting</span><span class="p">[</span><span class="s2">&quot;cutoff&quot;</span><span class="p">]</span>
                <span class="k">if</span> <span class="n">scale</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
                    <span class="n">radial_cutoff</span> <span class="o">=</span> <span class="o">-</span><span class="n">math</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">cutoff</span><span class="p">)</span><span class="o">/</span><span class="n">scale</span>
                <span class="n">parameters</span> <span class="o">=</span> <span class="p">{</span>
                    <span class="sa">b</span><span class="s2">&quot;scale&quot;</span><span class="p">:</span> <span class="n">scale</span><span class="p">,</span>
                    <span class="sa">b</span><span class="s2">&quot;cutoff&quot;</span><span class="p">:</span> <span class="n">cutoff</span>
                <span class="p">}</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">weighting_function</span> <span class="o">=</span> <span class="s2">&quot;unity&quot;</span>

        <span class="c1"># Determine the geometry function</span>
        <span class="n">geom_func_name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k2</span><span class="p">[</span><span class="s2">&quot;geometry&quot;</span><span class="p">][</span><span class="s2">&quot;function&quot;</span><span class="p">]</span>

        <span class="c1"># If needed, create the extended system</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">periodic</span><span class="p">:</span>
            <span class="n">centers</span> <span class="o">=</span> <span class="n">system</span><span class="o">.</span><span class="n">get_positions</span><span class="p">()</span>
            <span class="n">ext_system</span><span class="p">,</span> <span class="n">cell_indices</span> <span class="o">=</span> <span class="n">dscribe</span><span class="o">.</span><span class="n">utils</span><span class="o">.</span><span class="n">geometry</span><span class="o">.</span><span class="n">get_extended_system</span><span class="p">(</span>
                <span class="n">system</span><span class="p">,</span>
                <span class="n">radial_cutoff</span><span class="p">,</span>
                <span class="n">centers</span><span class="p">,</span>
                <span class="n">return_cell_indices</span><span class="o">=</span><span class="kc">True</span>
            <span class="p">)</span>
            <span class="n">ext_system</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="n">from_atoms</span><span class="p">(</span><span class="n">ext_system</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">ext_system</span> <span class="o">=</span> <span class="n">system</span>
            <span class="n">cell_indices</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="nb">len</span><span class="p">(</span><span class="n">system</span><span class="p">),</span> <span class="mi">3</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="nb">int</span><span class="p">)</span>

        <span class="n">cmbtr</span> <span class="o">=</span> <span class="n">MBTRWrapper</span><span class="p">(</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">atomic_number_to_index</span><span class="p">,</span>
            <span class="n">interaction_limit</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_interaction_limit</span><span class="p">,</span>
            <span class="n">indices</span><span class="o">=</span><span class="n">cell_indices</span>
        <span class="p">)</span>

        <span class="c1"># If radial cutoff is finite, use it to calculate the sparse</span>
        <span class="c1"># distance matrix to reduce computational complexity from O(n^2) to</span>
        <span class="c1"># O(n log(n))</span>
        <span class="n">n_atoms</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">ext_system</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">radial_cutoff</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">dmat</span> <span class="o">=</span> <span class="n">ext_system</span><span class="o">.</span><span class="n">get_distance_matrix_within_radius</span><span class="p">(</span><span class="n">radial_cutoff</span><span class="p">)</span>
            <span class="n">adj_list</span> <span class="o">=</span> <span class="n">dscribe</span><span class="o">.</span><span class="n">utils</span><span class="o">.</span><span class="n">geometry</span><span class="o">.</span><span class="n">get_adjacency_list</span><span class="p">(</span><span class="n">dmat</span><span class="p">)</span>
            <span class="n">dmat_dense</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">full</span><span class="p">((</span><span class="n">n_atoms</span><span class="p">,</span> <span class="n">n_atoms</span><span class="p">),</span> <span class="n">sys</span><span class="o">.</span><span class="n">float_info</span><span class="o">.</span><span class="n">max</span><span class="p">)</span>  <span class="c1"># The non-neighbor values are treated as &quot;infinitely far&quot;.</span>
            <span class="n">dmat_dense</span><span class="p">[</span><span class="n">dmat</span><span class="o">.</span><span class="n">row</span><span class="p">,</span> <span class="n">dmat</span><span class="o">.</span><span class="n">col</span><span class="p">]</span> <span class="o">=</span> <span class="n">dmat</span><span class="o">.</span><span class="n">data</span>
        <span class="c1"># If no weighting is used, the full distance matrix is calculated</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">dmat_dense</span> <span class="o">=</span> <span class="n">ext_system</span><span class="o">.</span><span class="n">get_distance_matrix</span><span class="p">()</span>
            <span class="n">adj_list</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">tile</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="n">n_atoms</span><span class="p">),</span> <span class="p">(</span><span class="n">n_atoms</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>

        <span class="n">k2_map</span> <span class="o">=</span> <span class="n">cmbtr</span><span class="o">.</span><span class="n">get_k2</span><span class="p">(</span>
            <span class="n">ext_system</span><span class="o">.</span><span class="n">get_atomic_numbers</span><span class="p">(),</span>
            <span class="n">distances</span><span class="o">=</span><span class="n">dmat_dense</span><span class="p">,</span>
            <span class="n">neighbours</span><span class="o">=</span><span class="n">adj_list</span><span class="p">,</span>
            <span class="n">geom_func</span><span class="o">=</span><span class="n">geom_func_name</span><span class="o">.</span><span class="n">encode</span><span class="p">(),</span>
            <span class="n">weight_func</span><span class="o">=</span><span class="n">weighting_function</span><span class="o">.</span><span class="n">encode</span><span class="p">(),</span>
            <span class="n">parameters</span><span class="o">=</span><span class="n">parameters</span><span class="p">,</span>
            <span class="n">start</span><span class="o">=</span><span class="n">start</span><span class="p">,</span>
            <span class="n">stop</span><span class="o">=</span><span class="n">stop</span><span class="p">,</span>
            <span class="n">sigma</span><span class="o">=</span><span class="n">sigma</span><span class="p">,</span>
            <span class="n">n</span><span class="o">=</span><span class="n">n</span><span class="p">,</span>
        <span class="p">)</span>

        <span class="c1"># Depending of flattening, use either a sparse matrix or a dense one.</span>
        <span class="n">n_elem</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">n_elements</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">flatten</span><span class="p">:</span>
            <span class="n">k2</span> <span class="o">=</span> <span class="n">lil_matrix</span><span class="p">(</span>
                <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">n_elem</span><span class="o">*</span><span class="p">(</span><span class="n">n_elem</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">n</span><span class="p">)),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">float32</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">k2</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="bp">self</span><span class="o">.</span><span class="n">n_elements</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">n_elements</span><span class="p">,</span> <span class="n">n</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">float32</span><span class="p">)</span>

        <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">gaussian_sum</span> <span class="ow">in</span> <span class="n">k2_map</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
            <span class="n">i</span> <span class="o">=</span> <span class="n">key</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
            <span class="n">j</span> <span class="o">=</span> <span class="n">key</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>

            <span class="c1"># This is the index of the spectrum. It is given by enumerating the</span>
            <span class="c1"># elements of an upper triangular matrix from left to right and top</span>
            <span class="c1"># to bottom.</span>
            <span class="n">m</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">j</span> <span class="o">+</span> <span class="n">i</span><span class="o">*</span><span class="n">n_elem</span> <span class="o">-</span> <span class="n">i</span><span class="o">*</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span>

            <span class="c1"># Denormalize if requested</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">normalize_gaussians</span><span class="p">:</span>
                <span class="n">max_val</span> <span class="o">=</span> <span class="mi">1</span><span class="o">/</span><span class="p">(</span><span class="n">sigma</span><span class="o">*</span><span class="n">math</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">2</span><span class="o">*</span><span class="n">math</span><span class="o">.</span><span class="n">pi</span><span class="p">))</span>
                <span class="n">gaussian_sum</span> <span class="o">/=</span> <span class="n">max_val</span>

            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">flatten</span><span class="p">:</span>
                <span class="n">start</span> <span class="o">=</span> <span class="n">m</span><span class="o">*</span><span class="n">n</span>
                <span class="n">end</span> <span class="o">=</span> <span class="p">(</span><span class="n">m</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="n">n</span>
                <span class="n">k2</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="n">start</span><span class="p">:</span><span class="n">end</span><span class="p">]</span> <span class="o">=</span> <span class="n">gaussian_sum</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">k2</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="p">:]</span> <span class="o">=</span> <span class="n">gaussian_sum</span>

        <span class="k">return</span> <span class="n">k2</span>

    <span class="k">def</span> <span class="nf">_get_k3</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">system</span><span class="p">):</span>
        <span class="sd">&quot;&quot;&quot;Calculates the third order terms.</span>

<span class="sd">        Returns:</span>
<span class="sd">            1D ndarray: flattened K3 values.</span>
<span class="sd">        &quot;&quot;&quot;</span>
        <span class="n">grid</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k3</span><span class="p">[</span><span class="s2">&quot;grid&quot;</span><span class="p">]</span>
        <span class="n">start</span> <span class="o">=</span> <span class="n">grid</span><span class="p">[</span><span class="s2">&quot;min&quot;</span><span class="p">]</span>
        <span class="n">stop</span> <span class="o">=</span> <span class="n">grid</span><span class="p">[</span><span class="s2">&quot;max&quot;</span><span class="p">]</span>
        <span class="n">n</span> <span class="o">=</span> <span class="n">grid</span><span class="p">[</span><span class="s2">&quot;n&quot;</span><span class="p">]</span>
        <span class="n">sigma</span> <span class="o">=</span> <span class="n">grid</span><span class="p">[</span><span class="s2">&quot;sigma&quot;</span><span class="p">]</span>

        <span class="c1"># Determine the weighting function and possible radial cutoff</span>
        <span class="n">radial_cutoff</span> <span class="o">=</span> <span class="kc">None</span>
        <span class="n">weighting</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k3</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">&quot;weighting&quot;</span><span class="p">)</span>
        <span class="n">parameters</span> <span class="o">=</span> <span class="p">{}</span>
        <span class="k">if</span> <span class="n">weighting</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">weighting_function</span> <span class="o">=</span> <span class="n">weighting</span><span class="p">[</span><span class="s2">&quot;function&quot;</span><span class="p">]</span>
            <span class="k">if</span> <span class="n">weighting_function</span> <span class="o">==</span> <span class="s2">&quot;exponential&quot;</span> <span class="ow">or</span> <span class="n">weighting_function</span> <span class="o">==</span> <span class="s2">&quot;exp&quot;</span><span class="p">:</span>
                <span class="n">scale</span> <span class="o">=</span> <span class="n">weighting</span><span class="p">[</span><span class="s2">&quot;scale&quot;</span><span class="p">]</span>
                <span class="n">cutoff</span> <span class="o">=</span> <span class="n">weighting</span><span class="p">[</span><span class="s2">&quot;cutoff&quot;</span><span class="p">]</span>
                <span class="k">if</span> <span class="n">scale</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
                    <span class="n">radial_cutoff</span> <span class="o">=</span> <span class="o">-</span><span class="mf">0.5</span><span class="o">*</span><span class="n">math</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">cutoff</span><span class="p">)</span><span class="o">/</span><span class="n">scale</span>
                <span class="n">parameters</span> <span class="o">=</span> <span class="p">{</span>
                    <span class="sa">b</span><span class="s2">&quot;scale&quot;</span><span class="p">:</span> <span class="n">scale</span><span class="p">,</span>
                    <span class="sa">b</span><span class="s2">&quot;cutoff&quot;</span><span class="p">:</span> <span class="n">cutoff</span>
                <span class="p">}</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">weighting_function</span> <span class="o">=</span> <span class="s2">&quot;unity&quot;</span>

        <span class="c1"># Determine the geometry function</span>
        <span class="n">geom_func_name</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">k3</span><span class="p">[</span><span class="s2">&quot;geometry&quot;</span><span class="p">][</span><span class="s2">&quot;function&quot;</span><span class="p">]</span>

        <span class="c1"># If needed, create the extended system</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">periodic</span><span class="p">:</span>
            <span class="n">centers</span> <span class="o">=</span> <span class="n">system</span><span class="o">.</span><span class="n">get_positions</span><span class="p">()</span>
            <span class="n">ext_system</span><span class="p">,</span> <span class="n">cell_indices</span> <span class="o">=</span> <span class="n">dscribe</span><span class="o">.</span><span class="n">utils</span><span class="o">.</span><span class="n">geometry</span><span class="o">.</span><span class="n">get_extended_system</span><span class="p">(</span>
                <span class="n">system</span><span class="p">,</span>
                <span class="n">radial_cutoff</span><span class="p">,</span>
                <span class="n">centers</span><span class="p">,</span>
                <span class="n">return_cell_indices</span><span class="o">=</span><span class="kc">True</span>
            <span class="p">)</span>
            <span class="n">ext_system</span> <span class="o">=</span> <span class="n">System</span><span class="o">.</span><span class="n">from_atoms</span><span class="p">(</span><span class="n">ext_system</span><span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">ext_system</span> <span class="o">=</span> <span class="n">system</span>
            <span class="n">cell_indices</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="nb">len</span><span class="p">(</span><span class="n">system</span><span class="p">),</span> <span class="mi">3</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="nb">int</span><span class="p">)</span>

        <span class="n">cmbtr</span> <span class="o">=</span> <span class="n">MBTRWrapper</span><span class="p">(</span>
            <span class="bp">self</span><span class="o">.</span><span class="n">atomic_number_to_index</span><span class="p">,</span>
            <span class="n">interaction_limit</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">_interaction_limit</span><span class="p">,</span>
            <span class="n">indices</span><span class="o">=</span><span class="n">cell_indices</span>
        <span class="p">)</span>

        <span class="c1"># If radial cutoff is finite, use it to calculate the sparse</span>
        <span class="c1"># distance matrix to reduce computational complexity from O(n^2) to</span>
        <span class="c1"># O(n log(n))</span>
        <span class="n">n_atoms</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">ext_system</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">radial_cutoff</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
            <span class="n">dmat</span> <span class="o">=</span> <span class="n">ext_system</span><span class="o">.</span><span class="n">get_distance_matrix_within_radius</span><span class="p">(</span><span class="n">radial_cutoff</span><span class="p">)</span>
            <span class="n">adj_list</span> <span class="o">=</span> <span class="n">dscribe</span><span class="o">.</span><span class="n">utils</span><span class="o">.</span><span class="n">geometry</span><span class="o">.</span><span class="n">get_adjacency_list</span><span class="p">(</span><span class="n">dmat</span><span class="p">)</span>
            <span class="n">dmat_dense</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">full</span><span class="p">((</span><span class="n">n_atoms</span><span class="p">,</span> <span class="n">n_atoms</span><span class="p">),</span> <span class="n">sys</span><span class="o">.</span><span class="n">float_info</span><span class="o">.</span><span class="n">max</span><span class="p">)</span>  <span class="c1"># The non-neighbor values are treated as &quot;infinitely far&quot;.</span>
            <span class="n">dmat_dense</span><span class="p">[</span><span class="n">dmat</span><span class="o">.</span><span class="n">col</span><span class="p">,</span> <span class="n">dmat</span><span class="o">.</span><span class="n">row</span><span class="p">]</span> <span class="o">=</span> <span class="n">dmat</span><span class="o">.</span><span class="n">data</span>
        <span class="c1"># If no weighting is used, the full distance matrix is calculated</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">dmat_dense</span> <span class="o">=</span> <span class="n">ext_system</span><span class="o">.</span><span class="n">get_distance_matrix</span><span class="p">()</span>
            <span class="n">adj_list</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">tile</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">arange</span><span class="p">(</span><span class="n">n_atoms</span><span class="p">),</span> <span class="p">(</span><span class="n">n_atoms</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span>

        <span class="n">k3_map</span> <span class="o">=</span> <span class="n">cmbtr</span><span class="o">.</span><span class="n">get_k3</span><span class="p">(</span>
            <span class="n">ext_system</span><span class="o">.</span><span class="n">get_atomic_numbers</span><span class="p">(),</span>
            <span class="n">distances</span><span class="o">=</span><span class="n">dmat_dense</span><span class="p">,</span>
            <span class="n">neighbours</span><span class="o">=</span><span class="n">adj_list</span><span class="p">,</span>
            <span class="n">geom_func</span><span class="o">=</span><span class="n">geom_func_name</span><span class="o">.</span><span class="n">encode</span><span class="p">(),</span>
            <span class="n">weight_func</span><span class="o">=</span><span class="n">weighting_function</span><span class="o">.</span><span class="n">encode</span><span class="p">(),</span>
            <span class="n">parameters</span><span class="o">=</span><span class="n">parameters</span><span class="p">,</span>
            <span class="n">start</span><span class="o">=</span><span class="n">start</span><span class="p">,</span>
            <span class="n">stop</span><span class="o">=</span><span class="n">stop</span><span class="p">,</span>
            <span class="n">sigma</span><span class="o">=</span><span class="n">sigma</span><span class="p">,</span>
            <span class="n">n</span><span class="o">=</span><span class="n">n</span><span class="p">,</span>
        <span class="p">)</span>

        <span class="c1"># Depending of flattening, use either a sparse matrix or a dense one.</span>
        <span class="n">n_elem</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">n_elements</span>
        <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">flatten</span><span class="p">:</span>
            <span class="n">k3</span> <span class="o">=</span> <span class="n">lil_matrix</span><span class="p">(</span>
                <span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nb">int</span><span class="p">(</span><span class="n">n_elem</span><span class="o">*</span><span class="n">n_elem</span><span class="o">*</span><span class="p">(</span><span class="n">n_elem</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="o">*</span><span class="n">n</span><span class="p">)),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">float32</span>
            <span class="p">)</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="n">k3</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">zeros</span><span class="p">((</span><span class="n">n_elem</span><span class="p">,</span> <span class="n">n_elem</span><span class="p">,</span> <span class="n">n_elem</span><span class="p">,</span> <span class="n">n</span><span class="p">),</span> <span class="n">dtype</span><span class="o">=</span><span class="n">np</span><span class="o">.</span><span class="n">float32</span><span class="p">)</span>

        <span class="k">for</span> <span class="n">key</span><span class="p">,</span> <span class="n">gaussian_sum</span> <span class="ow">in</span> <span class="n">k3_map</span><span class="o">.</span><span class="n">items</span><span class="p">():</span>
            <span class="n">i</span> <span class="o">=</span> <span class="n">key</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
            <span class="n">j</span> <span class="o">=</span> <span class="n">key</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
            <span class="n">k</span> <span class="o">=</span> <span class="n">key</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span>

            <span class="c1"># This is the index of the spectrum. It is given by enumerating the</span>
            <span class="c1"># elements of a three-dimensional array where for valid elements</span>
            <span class="c1"># k&gt;=i. The enumeration begins from [0, 0, 0], and ends at [n_elem,</span>
            <span class="c1"># n_elem, n_elem], looping the elements in the order j, i, k.</span>
            <span class="n">m</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">j</span><span class="o">*</span><span class="n">n_elem</span><span class="o">*</span><span class="p">(</span><span class="n">n_elem</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span> <span class="o">+</span> <span class="n">k</span> <span class="o">+</span> <span class="n">i</span><span class="o">*</span><span class="n">n_elem</span> <span class="o">-</span> <span class="n">i</span><span class="o">*</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">/</span><span class="mi">2</span><span class="p">)</span>

            <span class="c1"># Denormalize if requested</span>
            <span class="k">if</span> <span class="ow">not</span> <span class="bp">self</span><span class="o">.</span><span class="n">normalize_gaussians</span><span class="p">:</span>
                <span class="n">max_val</span> <span class="o">=</span> <span class="mi">1</span><span class="o">/</span><span class="p">(</span><span class="n">sigma</span><span class="o">*</span><span class="n">math</span><span class="o">.</span><span class="n">sqrt</span><span class="p">(</span><span class="mi">2</span><span class="o">*</span><span class="n">math</span><span class="o">.</span><span class="n">pi</span><span class="p">))</span>
                <span class="n">gaussian_sum</span> <span class="o">/=</span> <span class="n">max_val</span>

            <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">flatten</span><span class="p">:</span>
                <span class="n">start</span> <span class="o">=</span> <span class="n">m</span><span class="o">*</span><span class="n">n</span>
                <span class="n">end</span> <span class="o">=</span> <span class="p">(</span><span class="n">m</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">*</span><span class="n">n</span>
                <span class="n">k3</span><span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="n">start</span><span class="p">:</span><span class="n">end</span><span class="p">]</span> <span class="o">=</span> <span class="n">gaussian_sum</span>
            <span class="k">else</span><span class="p">:</span>
                <span class="n">k3</span><span class="p">[</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">,</span> <span class="n">k</span><span class="p">,</span> <span class="p">:]</span> <span class="o">=</span> <span class="n">gaussian_sum</span>

        <span class="k">return</span> <span class="n">k3</span></div>
</pre></div>

           </div>
           
          </div>
          <footer>
  

  <hr/>

  <div role="contentinfo">
    <p>
        &copy; Copyright 

    </p>
  </div>
  Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>. 

</footer>

        </div>
      </div>

    </section>

  </div>
  
  <div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions">
    <span class="rst-current-version" data-toggle="rst-current-version">
      <span class="fa fa-book"> Versions</span>
      v: 0.3.0a0
      <span class="fa fa-caret-down"></span>
    </span>
    <div class="rst-other-versions">
      <dl>
        <dt>Versions</dt>
        
          <dd><a href="https://singroup.github.io/dscribe/dev">0.3.0a0 (development)</a></dd>
        
          <dd><a href="https://singroup.github.io/dscribe">0.2.9 (latest stable)</a></dd>
        
      </dl>
    </div>
  </div>


  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script>

  
  
    
   

</body>
</html>